package jpave.query_interface;
/**
 * Called when a row is selected from the Contigs or pairs table
 * Displays top row of buttons (display type drop down, Prev, Next)
 * Shows Contig tabs on left of screen
 * Initiates computation and display of panels 
 * 	see MultiAlignmentPanel which invokes ContigPanel and PairwiseAligmentPanel
 */

import java.util.Vector;
import java.util.TreeSet;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import util.methods.UIHelpers;
import util.ui.MenuMapper;
import util.ui.MenuTreeNode;
import util.Debug.ErrorReport;
import jpave.dataholders.BlastHitData;
import jpave.dataholders.MainData;
import jpave.dataholders.AlignmentData;

public class MainTopRowTab extends Tab 
{
	private static final boolean DEBUG = false;
	private Color buttonColor = new Color(230, 230, 255); 
	
	// these variables define where and how this is called
	private int displayNumCtg;
	private int numDBhits=0; 
	private short parent;
	private short ctgTab = 1;
	private short pairTab = 2;
	private short capTab = 3;
	
	public MainTopRowTab ( JPaveFrame theFrame,
                			MainData listData, 
                			Tab parentTab,					
                			int recordNum,
                			int [] prevContigDisplaySettings)
	{
		super(theFrame, parentTab);
		this.prevContigDisplaySettings = prevContigDisplaySettings;
		paveFrame = theFrame;
		nRecordNum = recordNum; 								
		ctgListData = listData;
		
		// CAP and displayNumCtg control what options are provide
		displayNumCtg = listData.getTotalContigs();
		
		if (parentTab == null) parent = capTab;
		else if (parentTab instanceof ContigListTab ||
				(parentTab instanceof BasicQueryTab)) {
			parent=ctgTab;
		}
		else if (parentTab instanceof ContigPairListTab) {
			parent=pairTab;
			try {
				BlastHitData hitData = 
				 theFrame.selectedSession.loadPairHitData(
						 listData.getCtgIDAt(0), listData.getCtgIDAt(1));
				listData.setSharedHits(hitData);
				numDBhits = hitData.getCntSharedHits();
			}
			catch (Exception e) {
				ErrorReport.reportError(e, "Internal error: MainTopRow getting shared hits");
			}
		}
	
		if ((parent == pairTab && displayNumCtg > 2) ||
			(parent != pairTab && displayNumCtg > 1)) {
			// this can happen when running CAP or phrap, so not an error
			//System.err.println("***Internal error: too many contigs selected");
			displayNumCtg = (parent == pairTab) ? 2 : 1;
		}
		/********************************************
		 *  XXX Create dropdown menu of contig/pairwise display options
		 */
		displayDropDown = new JComboBox ();
		displayDropDown.setBackground(buttonColor);

		if (displayNumCtg==1 && parent != capTab) { // Overview of single contig
			menuUToverview = new MenuMapper ( ShowUToverview, SHOW_UT_OVERVIEW );
			displayDropDown.addItem( menuUToverview );
			// CAS 5/3/13 re-enabled for  v1.1
			if(getParentFrame().hasGOs()) {
				menuUTGO = new MenuMapper( ShowUTGO, SHOW_UT_GO );
				displayDropDown.addItem( menuUTGO );
			}
		}
		else if (displayNumCtg!=1) {	// pairs view 
			menuPWalign = new MenuMapper(      
						ShowPWbestFrame, SHOW_PW_BEST_FRAME);
			displayDropDown.addItem(menuPWalign);
			MenuMapper menuAllAlign = new MenuMapper ( ShowPWallFrames, SHOW_PW_ALL_FRAMES );
			displayDropDown.addItem( menuAllAlign );
		}		
		
		MenuMapper menuESTAlign = null;
		if (paveFrame.hasAssembly()) {
			menuESTAlign = new MenuMapper ( ShowESTAlignments, SHOW_EST_ALIGNMENTS );
			displayDropDown.addItem( menuESTAlign );
			
			MenuMapper menuSNPAlign = new MenuMapper ( ShowTableOfSNPs, SHOW_TABLE_OF_SNPS );
			displayDropDown.addItem( menuSNPAlign );	
		}
		else {
			MenuMapper menuShowSeq = new MenuMapper ( ShowUnitransSeq, SHOW_EST_ALIGNMENTS );
			displayDropDown.addItem( menuShowSeq );
		}
		
		if (parent != capTab) {
			if (displayNumCtg==1) // just different label
				menuViewOff = new MenuMapper ( ShowUTviewOff, SHOW_VIEW_OFF);
			else 
				menuViewOff = new MenuMapper ( ShowPWviewOff, SHOW_VIEW_OFF);
			displayDropDown.addItem( menuViewOff);
		}		
		
		/**************************************************
		 * XXX  Create dropdown menu of DB hit align display options
		 */
		alignDropDown = new JComboBox ();
		alignDropDown.setBackground(buttonColor);
		
		if (displayNumCtg==1 ) {// just different label			
			menuBestHitAlign = new MenuMapper ( Align32Sequences, ALIGN_BEST_SEQUENCES);
			alignDropDown.addItem( menuBestHitAlign );
			
			MenuMapper menu1HitAlign = new MenuMapper ( AlignOVtable, ALIGN_OV_TABLE);
			alignDropDown.addItem( menu1HitAlign );

			MenuMapper menuSelect = new MenuMapper ( AlignSelect, ALIGN_SELECTED);
			alignDropDown.addItem( menuSelect );
			
			MenuMapper menuSelectF = new MenuMapper ( AlignSelectAll, ALIGN_SELECTED_ALL);
			alignDropDown.addItem( menuSelectF );
			
			menuAlignOff = new MenuMapper ( AlignOffSequences, ALIGN_OFF_SEQUENCES);
			alignDropDown.addItem( menuAlignOff );
		}
		else {
			menuFirst3 = new MenuMapper ( AlignFirst3Shared, ALIGN_FIRST3_SHARED);
			alignDropDown.addItem( menuFirst3 );
			
			MenuMapper menuTotalHitAlign = new MenuMapper ( Align0sequences, ALIGN_ALL_SHARED);
			alignDropDown.addItem( menuTotalHitAlign );
			
			menuAlignOff = new MenuMapper ( AlignOffSeqShared, ALIGN_OFF_SEQUENCES);
			alignDropDown.addItem( menuAlignOff );
		}
			
		displayDropDown.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				displayTypeInit();
			}
		});
		
		alignDropDown.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				alignTypeInit();
			}
		});
		if (displayNumCtg > 1 && numDBhits==0) 
			alignDropDown.setEnabled(false);
			
		// Create prev and next buttons
		JButton btnPrev = new JButton("<<Prev");
		btnPrev.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {				
				if(displayedJPanel != null)
					setPrevDisplaySettings(((MainToolBarPanel)displayedJPanel).getDisplaySettings());
				if (getParentTab() instanceof ContigListTab) {
					addNewTab( ((ContigListTab)getParentTab()).getPrevRowNum( 
							nRecordNum ) );
				}
				else if (getParentTab() instanceof ContigPairListTab) {
					addNewTab( ((ContigPairListTab)getParentTab()).getPrevRowNum( 
							nRecordNum ) );
				}
				else if(getParentTab() instanceof BasicQueryTab) {
					if(((BasicQueryTab)getParentTab()).getPrevRowNum(nRecordNum) >= 0)
						addNewTab(((BasicQueryTab)getParentTab()).getPrevRowNum(
								nRecordNum));
				}
			}
		});
		btnPrev.setBackground(buttonColor);

		JButton btnNext = new JButton("Next>>");
		btnNext.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(displayedJPanel != null) {
					setPrevDisplaySettings(((MainToolBarPanel)displayedJPanel).getDisplaySettings());
				}
				if (getParentTab() instanceof ContigListTab) { 
					addNewTab( ((ContigListTab) getParentTab()).getNextRowNum( nRecordNum ) );
				}
				else if (getParentTab() instanceof ContigPairListTab) {
					addNewTab( ((ContigPairListTab) getParentTab()).getNextRowNum( nRecordNum ) );
				}
				else if(getParentTab() instanceof BasicQueryTab) {
					if(((BasicQueryTab)getParentTab()).getNextRowNum(nRecordNum) >= 0)
						addNewTab(((BasicQueryTab)getParentTab()).getNextRowNum(nRecordNum));
				}
			}
		});
		btnNext.setBackground(buttonColor);
		
		if (parent == capTab)
		{
			btnPrev.setVisible(false);
			btnNext.setVisible(false);
		}
		if (recordNum < 0)
		{
			btnPrev.setEnabled(false);
			btnNext.setEnabled(false);
		}

		// Top panel with buttons and drop-down		
		JPanel topPanel = new JPanel ( );
		topPanel.setLayout( new BoxLayout ( topPanel, BoxLayout.X_AXIS ) );
		topPanel.add( Box.createHorizontalStrut(5) );
		topPanel.add( new JLabel ("Show") ); 						
		topPanel.add( Box.createHorizontalStrut(5) );
		topPanel.add( displayDropDown ); 
		topPanel.add( Box.createHorizontalStrut(5) );
		if (parent != capTab) {
			topPanel.add( new JLabel ("or") ); 
			topPanel.add( Box.createHorizontalStrut(5) );
			topPanel.add( alignDropDown ); 
		}
		topPanel.add( Box.createHorizontalGlue() );
		topPanel.add( Box.createHorizontalStrut(5) );
		topPanel.add( btnPrev ); 	
		topPanel.add( Box.createHorizontalStrut(5) );
		topPanel.add( btnNext ); 	
		topPanel.add( Box.createHorizontalStrut(5) );
		
		topPanel.setMaximumSize( new Dimension ( Integer.MAX_VALUE, 
				(int)topPanel.getPreferredSize ().getHeight() ) );
		topPanel.setBackground(Color.white);
		super.setBackground(Color.white);
			
		bottomPanel = new JPanel ();
		
		// Add to the called object's panel
		setLayout( new BoxLayout ( this, BoxLayout.Y_AXIS ) );
		add ( Box.createVerticalStrut(5) );
		add ( topPanel );
		add ( Box.createVerticalStrut(5) );
		add ( bottomPanel );

		/*************************************************
		 * XXX initial display
		 */
		if (displayNumCtg==1 && parent != capTab) 
			displayDropDown.setSelectedItem( menuUToverview );
		else if (parent == capTab) // the contig has capped 
			displayDropDown.setSelectedItem( menuESTAlign );
		else
			displayDropDown.setSelectedItem( menuPWalign );	
	}
	
	// called on ActionPerformed for displaydropdown
	private void displayTypeInit()
	{
		// So this a bit crazy, but otherwise the event for closing the
		// drop down menu never seems to come, and all of the other 
		// UI changes don't happen...
		if (internalSelect) return;
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				MenuMapper selection = (MenuMapper) displayDropDown.getSelectedItem();
				int displayType = selection.asInt();
				int alignType;
				
				internalSelect = true;
				if (displayType == SHOW_VIEW_OFF) {
					if (menuBestHitAlign != null) {
						alignType = ALIGN_BEST_SEQUENCES;
						alignDropDown.setSelectedItem( menuBestHitAlign);
					}
					else if (menuFirst3 != null) {
						alignType = 	ALIGN_FIRST3_SHARED;
						alignDropDown.setSelectedItem( menuFirst3);
					}
					else {
						System.err.println("Internal error in displayTypeInit");
						alignType = ALIGN_OFF_SEQUENCES;
						alignDropDown.setSelectedItem( menuAlignOff);
					}
				}
				else {
					alignType = ALIGN_OFF_SEQUENCES;
					alignDropDown.setSelectedItem( menuAlignOff);
				}
				internalSelect = false;
				
				displayTypeLoad(displayType, alignType);
			}
		});
	}
	// called on ActionPerformed for aligndropdown
	private void alignTypeInit()
	{
		if (internalSelect) return;
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				MenuMapper selection = (MenuMapper) alignDropDown.getSelectedItem();
				int alignType = selection.asInt();				
				int displayType;
				
				internalSelect = true;
				if (alignType == ALIGN_OFF_SEQUENCES && menuUToverview!=null) {
					displayType = SHOW_UT_OVERVIEW;
					displayDropDown.setSelectedItem( menuUToverview );
				}	
				else if (alignType == ALIGN_OFF_SEQUENCES && menuPWalign !=null) {
					displayType = SHOW_PW_BEST_FRAME;
					displayDropDown.setSelectedItem( menuPWalign );
				}
				else {
					displayType=SHOW_VIEW_OFF;
					displayDropDown.setSelectedItem( menuViewOff );
				}
				internalSelect = false;
				
				displayTypeLoad(displayType, alignType);
			}
		});
	}
	// called on initialization of display (above) and on ActionaListener (below)
	private void displayTypeLoad ( int nDisplayType, int nAlignType )
	{
		try
		{
			if ( displayedJPanel != null  ) 
				selectedContigs = getSelectedContigIDs ( );

			loadContigDataAndDraw ( nDisplayType, nAlignType );
		} 		
		catch ( Exception err )
		{
			ErrorReport.reportError(err, "Internal error in displayTypeLoad " + nDisplayType + " " + nAlignType);
		}			
	}
	// XXX display for contig overview panel
	private void loadContigDataAndDraw ( int nDisplayAfterLoad, int nAlignAfterLoad ) throws Exception
	{	
		// the ESTs have been loaded and another option selected
		if ( loadedClusterData != null && 
				!bLoadBuriedSequenceDetail && !bLoadBuriedSequenceLocation) {
			displayDraw ( loadedClusterData, nDisplayAfterLoad, nAlignAfterLoad, null);
			return;
		}

		// Swap in a wait tab while we hit the database
		final int saveDisplayAfterLoad = nDisplayAfterLoad;
		final int saveAlignAfterLoad = nAlignAfterLoad;

		String message = "Loading ";
		if(loadedClusterData == null) message += "Sequence data ";  // CAS 12/26/14 - chg from Contig Data 
		if(bLoadBuriedSequenceDetail) message += "Buried(Detail) ";
		if(bLoadBuriedSequenceLocation) message += "Buried(Location) ";
		message += "; please wait... ";

		final Tab waitTab = new CenteredMessageTab ( message );
		
		final JPaveFrame theFrame = getParentFrame(); 
		theFrame.addTabAndRun(MainTopRowTab.this, null, waitTab, 
		  new JPaveFrame.RunnableCanThrow() {
			public void run() throws Throwable {

				//If the Contig data is not loaded, load now
				if(loadedClusterData == null) {
					loadedClusterData = 
						theFrame.selectedSession.loadContigSequences(ctgListData);
					if (loadedClusterData==null) return;
				}
				
				// Load buried if needed
				if(bLoadBuriedSequenceDetail) {
					if(bBuriedSequenceLocationLoaded) loadedClusterData.removeBuried();
			
					theFrame.selectedSession.loadContigBuriedSequences(loadedClusterData, false);
					
					bBuriedSequenceLocationLoaded = true;
					bBuriedSequenceDetailLoaded = true;
					bLoadBuriedSequenceDetail = false;

				}
				else if(bLoadBuriedSequenceLocation) {
					theFrame.selectedSession.loadContigBuriedSequences(loadedClusterData, true);
	
					bBuriedSequenceLocationLoaded = true;
					bLoadBuriedSequenceLocation = false;
				}
				displayDraw(loadedClusterData, saveDisplayAfterLoad, saveAlignAfterLoad, waitTab);
			}		
		});
	}
	
	private void  displayDraw ( MainData inCluster,
								int displayType, int alignType, Tab waitTab ) throws Exception
	{	
		boolean bHaveData = false;
		String strWaitMsg = "Please wait...";
		final JPaveFrame theFrame = getParentFrame(); 
		
		switch ( displayType )
		{
		case SHOW_UT_OVERVIEW:
			strWaitMsg = "Generating overview; please wait...";
			if ( overviewPanel != null ) {
				installOverviewPanel ( overviewPanel );
				bHaveData = true;
			}
			break;		
		case SHOW_UT_GO:
			if (overviewPanel.cntSelectedHits() !=0) {
				if (overviewPanel.cntSelectedHits() != 1) {
					JOptionPane.showMessageDialog(theFrame, 
							"Cannot show GOs for multiple selected. " +
							"Either select one or unselect all to see all GOs.", 
							"Selected GO", JOptionPane.PLAIN_MESSAGE);
			
					return;
				}
				else {
					String [] cur = overviewPanel.getSelectedHits();
					if (cur[0] != goHit) goPanel = null; /// XXX 
					goHit = cur[0];
				}
			}
			else {
				if (goHit != null) goPanel = null;
				goHit = null;
			}
			
			strWaitMsg = "Generating GO data; please wait...";
			if ( goPanel != null ) {
				installGOPanel ( goPanel);
				bHaveData = true;
			}
			break;
			
		case SHOW_EST_ALIGNMENTS:
			MainToolBarPanel showContigPanel = installESTPanel ( loadedClusterData );
			showContigPanel.setSelectedClones(strSelectedClones);
			bHaveData = true;
			
			//detect if Cluster is generated
			if(CAP3orPhrapTab.ResultIDExists(getID()) && inCluster.getTotalContigs() == 1)
				((MainToolBarPanel)displayedJPanel).ShowReplaceBtn(true, paveFrame.hasAssembly());
			else
				((MainToolBarPanel)displayedJPanel).ShowReplaceBtn(false, paveFrame.hasAssembly());
			break;
			
		case SHOW_TABLE_OF_SNPS: 
			strWaitMsg = "Finding SNPs, please wait...";
			if (snpPanel != null) {
				installSNPPanel ( snpPanel );
				bHaveData = true;
			}								
			break;				

		case SHOW_PW_BEST_FRAME:
            strWaitMsg = "Finding alignments using best frame, please wait...";
			if ( pairBestPanel != null ) {
				installMainPanel ( pairBestPanel );
				bHaveData = true;
			}
			break;
			
		case SHOW_PW_ALL_FRAMES:
            strWaitMsg = "Finding alignments in all frames, please wait...";
			if ( pairAllPanel != null ) {
				installMainPanel ( pairAllPanel );
				bHaveData = true;
			}
			break;
			
		case SHOW_VIEW_OFF:
			switch ( alignType )
			{
		
			case ALIGN_ALL_SHARED: // pairwise
				strWaitMsg = "Aligning all " + numDBhits + 
						" shared DB hit sequences; please wait...";
				if ( Hit0Panel != null ) {
					installMainPanel ( Hit0Panel );
					bHaveData = true;
				}
				break;
			case ALIGN_FIRST3_SHARED: //pairwise
				strWaitMsg = "Aligning first 3 shared DB hit sequences; please wait...";
				if ( HitF3Panel != null ) {
					installMainPanel ( HitF3Panel );
					bHaveData = true;
				}
				break;
				
			case ALIGN_BEST_SEQUENCES:
				strWaitMsg = "Aligning best hit sequence; please wait...";
				if ( Hit32Panel != null ) {
					installMainPanel ( Hit32Panel );
					bHaveData = true;
				}
				break;		
			case ALIGN_SELECTED:
				if (!checkIfSelected()) return;
				String [] x = checkNewSelected(displayedHits1);
				if (x!=null) { // new list
					HitSLPanel=null;
					displayedHits1 = x;
				}
	
				strWaitMsg = "Aligning selected set; please wait...";
				if ( HitSLPanel != null ) {
					installMainPanel ( HitSLPanel );
					bHaveData = true;
				}
				break;
			case ALIGN_SELECTED_ALL:
				if (!checkIfSelected()) return;
				x = checkNewSelected(displayedHits2);
				if (x!=null) { // new list
					HitSLAPanel=null;
					displayedHits2 = x;
				}

				strWaitMsg = "Aligning selected set in all frames; please wait...";
				if ( HitSLAPanel != null ) {
					installMainPanel ( HitSLAPanel );
					bHaveData = true;
				}
				break;
				
			case ALIGN_OV_TABLE:
				filterType = overviewPanel.getFilterType();
				switch (filterType) {
					case 1:
						strWaitMsg = "Aligning " + overviewPanel.getOlap() +
							" minimal overlap sequences; please wait...";
						if ( Hit1Panel != null ) {
							installMainPanel ( Hit1Panel );
							bHaveData = true;
						}
						break;
				
					case 2:
						strWaitMsg = "Aligning " + overviewPanel.getDBs() + " " +
								"top-3 per annoDB sequences; please wait...";
						if ( Hit2Panel != null ) {
							installMainPanel ( Hit2Panel );
							bHaveData = true;
						}
						break;
						
					case 4:
						strWaitMsg = "Aligning " + overviewPanel.getSpecies() + " " +
							"unique species sequences; please wait...";
						if ( Hit4Panel != null ) {
							installMainPanel ( Hit4Panel );
							bHaveData = true;
						}
						break;
				
					case 8:
						strWaitMsg = "Aligning " + overviewPanel.getGenes() + " " +
							" unique gene rep sequences; please wait...";
						if ( Hit8Panel != null ) {
							installMainPanel ( Hit8Panel );
							bHaveData = true;
						}
						break;
						
					case 32:
						strWaitMsg = "Aligning best hit sequence; please wait...";
						if ( Hit32Panel != null ) {
							installMainPanel ( Hit32Panel );
							bHaveData = true;
						}
						break;
						
					case 0:
						strWaitMsg = "Aligning all DB hit sequences; please wait...";
						if ( Hit0Panel != null ) {
							installMainPanel ( Hit0Panel );
							bHaveData = true;
						}
						break;
				} // end overview table switch
				break;
			} // end alignType
			break;
		default:
			System.err.println("Internal error MainTopRow: " + displayType + " " + alignType);
		} // end displayType

		if ( bHaveData ) {
			if ( waitTab != null ) { 
				theFrame.swapInTab( waitTab, getTitle(), MainTopRowTab.this ); 
			}
			return; /******************** Early Exit ************************/
		}
		
		// Swap in a wait tab while we run CAP3/blast	
		Tab oldTab = MainTopRowTab.this;
		if ( waitTab != null) oldTab = waitTab;

		final MainData holdClusterIn = inCluster;
		final int saveDisplay2 = displayType;
		final int saveAlign2 = alignType;
		final Tab tempTab = new CenteredMessageTab ( strWaitMsg );
		
		switch (saveDisplay2) 
		{
		case SHOW_TABLE_OF_SNPS: 
			//Mark 4-29-10 In case snp grouping may takes a long time, allows user to cancel
	        final InterThreadProgress progress = new InterThreadProgress ( getParentFrame() );
	        progress.swapInTabAndStartThread( this, "Grouping SNPs", 
				new InterThreadProgress.WorkerThread ()
				{
					public void run () throws Throwable
					{
	                    progress.setProgressLabel( 
	                    		"Waiting for SNP grouping to finish. (This may take awhile based on # of SNPs)" );
	        				snpPanel = new SNPMultiPanel ( holdClusterIn );
	        				installSNPPanel( snpPanel );
	        				progress.swapOutProgress(MainTopRowTab.this);
					}
				}
			);
	        break;
	        
		default:
			theFrame.addTabAndRun ( oldTab, null, tempTab, 
				new JPaveFrame.RunnableCanThrow ()
				{
					public void run () throws Throwable
					{
						switch ( saveDisplay2 )
						{						
						// All alignments: Basic, Show Contigs (if select more than one), Pairs
						case SHOW_PW_BEST_FRAME:
						case SHOW_PW_ALL_FRAMES:

							String label = "";
				             if (nRecordNum < 0) { // 
				                	if (getParentTab() instanceof ContigListTab) label = "Selected Sequences"; //+ nCount;
				                	else label = "Basic";
				             }
				             else label = "Similar sequence pair"; // PairwiseAlignment searches on 'pair'
				          
							short type = AlignmentData.firstResult;
							if (saveDisplay2==SHOW_PW_ALL_FRAMES) 
								type = AlignmentData.allResult;
							Vector<AlignmentData> pairs = 
								AlignmentData.pairAlignDisplay( holdClusterIn, label,
										getParentFrame().selectedSession, type);
							
							if (saveDisplay2==SHOW_PW_ALL_FRAMES)
								pairAllPanel = installMainPairAlignPanel( pairs );
							else
								pairBestPanel = installMainPairAlignPanel( pairs );
							break;
							
						case SHOW_UT_OVERVIEW:
							overviewPanel = new ContigOverviewPanel(paveFrame, holdClusterIn);
							installOverviewPanel(overviewPanel);
							break;
							
						case SHOW_UT_GO:
							goPanel = new ContigGOPanel(paveFrame, holdClusterIn, goHit);
							installGOPanel(goPanel);
							break;
							
						case SHOW_VIEW_OFF: // what is selected on pulldown
							switch ( saveAlign2)
							{						
							case ALIGN_FIRST3_SHARED:
								Vector<AlignmentData> hitF3 =  // no filter, first 3
									AlignmentData.DBhitsAlignDisplay(-1, holdClusterIn, paveFrame.isProteinDB()  );
								HitF3Panel = installMainPairAlignPanel( hitF3 );
								break;
								
							case ALIGN_ALL_SHARED:
								Vector<AlignmentData> hitall =  // all
									AlignmentData.DBhitsAlignDisplay(0, holdClusterIn, paveFrame.isProteinDB()  );
								Hit0Panel = installMainPairAlignPanel( hitall );
								break;
							
							case ALIGN_BEST_SEQUENCES:
								Vector<AlignmentData> hitbest =  // best according to blast
									AlignmentData.DBhitsAlignDisplay(32|16, holdClusterIn, paveFrame.isProteinDB() );
								Hit32Panel = installMainPairAlignPanel( hitbest );
								break;
								
							case ALIGN_SELECTED:
								Vector<AlignmentData> hitSL =  // selected hits CAS 3/30/15 was bestResult
									AlignmentData.DBhitsAlignDisplay(displayedHits1, holdClusterIn, 
											AlignmentData.frameResult, paveFrame.isProteinDB());
								HitSLPanel = installMainPairAlignPanel( hitSL );
								break;
							case ALIGN_SELECTED_ALL:
								Vector<AlignmentData> hitSLA =  // selected hits in all frames
									AlignmentData.DBhitsAlignDisplay(displayedHits2, holdClusterIn,  
											AlignmentData.allResult, paveFrame.isProteinDB() );
								HitSLAPanel = installMainPairAlignPanel( hitSLA );
								break;
								
							case ALIGN_OV_TABLE: // if Align overview table, it uses the filter type
									
								switch (filterType) {
								
									case 1:
									Vector<AlignmentData> hit1 =  // overlap
										AlignmentData.DBhitsAlignDisplay(1, holdClusterIn, paveFrame.isProteinDB()  );
									Hit1Panel = installMainPairAlignPanel( hit1 );
									break;
									
									case 2:
									Vector<AlignmentData> hit2 =  // top 3
										AlignmentData.DBhitsAlignDisplay(2, holdClusterIn, paveFrame.isProteinDB());
									Hit2Panel = installMainPairAlignPanel( hit2 );
									break;
									
									case 4:
									Vector<AlignmentData> hit4 =  // species
										AlignmentData.DBhitsAlignDisplay(4, holdClusterIn, paveFrame.isProteinDB()  );
									Hit4Panel = installMainPairAlignPanel( hit4 );
									break;
									
									case 8:
									Vector<AlignmentData> hit8 =  // gene
										AlignmentData.DBhitsAlignDisplay(8, holdClusterIn, paveFrame.isProteinDB()  );
									Hit8Panel = installMainPairAlignPanel( hit8 );
									break;
									
									case 32:
									Vector<AlignmentData> hit32 =  // best
										AlignmentData.DBhitsAlignDisplay(32|16, holdClusterIn, paveFrame.isProteinDB()  );
									Hit32Panel = installMainPairAlignPanel( hit32 );
									break;
									
									case 0:
									Vector<AlignmentData> hit0 =  // all
										AlignmentData.DBhitsAlignDisplay(0, holdClusterIn, paveFrame.isProteinDB()  );
									Hit0Panel = installMainPairAlignPanel( hit0 );
									break;
								}	// end filtertype
								break;

							} // end alignType
						break;
						default:
							System.err.println("Internal error in MainTopRowTap 2: " + saveDisplay2 + " " + saveAlign2);
						} // end displayType
							
						theFrame.swapInTab( tempTab, null, MainTopRowTab.this );
						
						// kludge to get consensus alignment to redraw, this is the only method that worked
						int d = theFrame.splitPane.getDividerLocation();
						theFrame.splitPane.setDividerLocation(d-1);
					}
				}
			);
		} // end switch
	}

	/***************************************************
	 * Prev Next tabs
	 **************************************************/
	private void addNewTab(int nNewRecordNum )
	{	
		Tab parentTab = (Tab)getParentTab();
		Tab newTab;
		String strTitle;
		
		// Add new contig tab
		if (parentTab instanceof ContigListTab) {
			strTitle = ((ContigListTab)parentTab).getContigIDAtRow(nNewRecordNum);
			newTab = getParentFrame().addNewContigTab( strTitle, parentTab, 
					nNewRecordNum, prevContigDisplaySettings );
		}
		else if(parentTab instanceof BasicQueryTab) {
			strTitle = ((BasicQueryTab)parentTab).getContigIDAtRow(nNewRecordNum);
			newTab = getParentFrame().addNewContigTab( strTitle, parentTab, 
					nNewRecordNum, prevContigDisplaySettings );
		}
		else { //  Add new pairs tab
			strTitle = "Pair # " + 	((ContigPairListTab)parentTab).getPairNumAtRow(nNewRecordNum);

			MainData theCluster = new MainData();
			String[] contigIDs = ((ContigPairListTab)parentTab).getContigIDsAtRow( nNewRecordNum );
			theCluster.addContigStub( contigIDs[0] );
			theCluster.addContigStub( contigIDs[1] );
			newTab = getParentFrame().addNewClusterTab( theCluster, parentTab, nNewRecordNum, 
					strTitle, prevContigDisplaySettings );
		}
		
		// Re-use existing menu tree node
		MenuTreeNode node = getMenuNode();
		newTab.setMenuNode(node);
		node.setText(strTitle);
		node.setUserObject(newTab);
	}
	
	/***************************************************************
	 * Install panels
	 ***************************************************************/

	private MainToolBarPanel installMainPairAlignPanel ( 
			Vector<AlignmentData> theAlignmentsToView )
	{
		MainToolBarPanel alignmentPanel = 
			MainToolBarPanel.createPairwisePanel (getParentFrame().getSettings(),
														theAlignmentsToView );
		installMainPanel ( alignmentPanel );
		alignmentPanel.applyDisplaySettings(prevContigDisplaySettings);
		return alignmentPanel;
	}
	
	private MainToolBarPanel installESTPanel ( 
			MainData theClusterToView ) throws Exception
	{
		int mode = 0;
		boolean needSynch = false;
		if(displayedJPanel != null) {
			mode= ((MainToolBarPanel)displayedJPanel).getShowBuriedMenuSelection();
			needSynch = true;
		}

		MainToolBarPanel clusterPanel = 
			MainToolBarPanel.createESTPanel( getParentFrame().getSettings(),
					theClusterToView, nRecordNum, getID(), paveFrame.hasNoAssembly());
		
		installMainPanel ( clusterPanel );
		clusterPanel.setShowBuriedAllPanels(paveFrame.hasNoAssembly());

		clusterPanel.applyDisplaySettings(prevContigDisplaySettings);
		//do something better??
		//Synchronize loading of buried ESTs, with the UI 
		if(needSynch)
			while(bLoadBuriedSequenceDetail || bLoadBuriedSequenceLocation);
		clusterPanel.setShowBuriedMenuSelection(mode, paveFrame.hasAssembly());
		prevContigDisplaySettings = null;
		
		return clusterPanel;
	}
	
	private void installOverviewPanel ( ContigOverviewPanel p ) 
	{			
		bottomPanel.removeAll();	
		bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
		bottomPanel.add ( p );
		displayedJPanel= null;
		// Work-around.  Otherwise the panel doesn't seem to show up
		setVisible(false);
		setVisible(true);
	}
	private void installGOPanel ( ContigGOPanel p ) 
	{			
		bottomPanel.removeAll();	
		bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
		bottomPanel.add ( p );
		displayedJPanel= null;
		// Work-around.  Otherwise the panel doesn't seem to show up
		setVisible(false);
		setVisible(true);
	}
	private void installSNPPanel ( SNPMultiPanel p ) 
	{			
		bottomPanel.removeAll();		
		bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
		bottomPanel.add ( p );
		displayedJPanel= null;
		// Work-around.  Otherwise the panel doesn't seem to show up
		setVisible(false);
		setVisible(true);
	}
	
	private void installMainPanel ( MainToolBarPanel thePanel )
	{
		if(showHideListener != null) thePanel.addShowHideListener(showHideListener);
		displayedJPanel = thePanel;
		thePanel.setSelectedContigs ( selectedContigs );// Pass in the select contigs from the
														// last one that we displayed		
		bottomPanel.removeAll();
		bottomPanel.setLayout( new BorderLayout () );
		bottomPanel.add( displayedJPanel, BorderLayout.CENTER );
		
		// Work-around.  Otherwise the panel doesn't seem to show up
		setVisible(false);
		setVisible(true);
	}
	private ActionListener showHideListener = 
		new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			try {
				int mode = ((MainToolBarPanel)displayedJPanel).getShowBuriedMenuSelection();
				//Check if we need to load anything, if we do set the appropriate flags
				if(loadedClusterData == null || 
					(mode == MainToolBarPanel.SHOW_BURIED_EST_LOCATION && 
						  !bBuriedSequenceLocationLoaded && !bBuriedSequenceDetailLoaded) ||
					(mode == MainToolBarPanel.SHOW_BURIED_EST_DETAIL && !bBuriedSequenceDetailLoaded))
				{
					if(mode == MainToolBarPanel.SHOW_BURIED_EST_LOCATION)
						bLoadBuriedSequenceLocation = true;
					else if(mode == MainToolBarPanel.SHOW_BURIED_EST_DETAIL)
						bLoadBuriedSequenceDetail = true;
				
					bottomPanel.removeAll();
					
					displayTypeLoad(SHOW_EST_ALIGNMENTS, ALIGN_OFF_SEQUENCES);
				}
				else
				{
					((MainToolBarPanel)displayedJPanel).setShowBuriedAllPanels(paveFrame.hasNoAssembly());
				}
			} 
			catch (Exception err) {
				ErrorReport.reportError(err, "Internal error: with listerner");
			}
		}
	};
	
	private boolean checkIfSelected() {
		if ( overviewPanel.cntSelectedHits() == 0 ) {
			JPaveFrame theFrame = (JPaveFrame)UIHelpers.findParentFrame( this );
			JOptionPane.showMessageDialog( 	theFrame, 
						"Please select the DB hit from the overview table that you wish to align.",
						"No DB hits Selected",
						JOptionPane.PLAIN_MESSAGE );
			return false;
		}
		return true;
	}
	
	private String [] checkNewSelected(String [] viewed) {
		String [] cur = overviewPanel.getSelectedHits();
		if (viewed == null) return cur;
		if (viewed.length != cur.length) return cur;
		
		for (int i=0; i< cur.length; i++) {
			for (int j=0; j< viewed.length; j++) {
				if (!cur[i].equals(viewed[j])) return cur;
			}
		}
		return null;
	}
	public TreeSet<String> getSelectedContigIDs ( )
	{
		MainToolBarPanel panel = (MainToolBarPanel)displayedJPanel;
		return panel.getSelectedContigIDs();
	}
	
	public void setSelectedClones(String strSelectedClones) {
		this.strSelectedClones = strSelectedClones;
	}
	
	public void setPrevDisplaySettings(int [] prevContigDisplaySettings)
	{
		this.prevContigDisplaySettings = prevContigDisplaySettings;
	}
	
	public void close()
	{
		displayDropDown = null;
		bottomPanel = null;
		displayedJPanel = null;
		if(selectedContigs != null) selectedContigs.clear();
		if(ctgListData != null) ctgListData.clear();
		if(loadedClusterData != null) loadedClusterData.clear();

		Hit32Panel = Hit8Panel = Hit4Panel = Hit2Panel = Hit1Panel = Hit0Panel = null;
		pairAllPanel = pairBestPanel = null;
		snpPanel = null;
	}
	public String getDescription () {
		String str = "Record number " + nRecordNum;
		if (getParentTab() instanceof ContigListTab) str += " Contig ";
		else str += " Pairs ";
		return str;
	}
	
	/***************************************************
	 * XXX Pairwise/unitran views
	 */
	static final private String ShowUTviewOff 	= 	"Align DB hits - on";
	static final private String ShowUToverview 	= 	"Overview";
	static final private String ShowUTGO 		= 	"View all GOs or from selected hit";

	static final private String ShowPWviewOff = 		"Pairwise views - off";
	static final private String ShowPWbestFrame = 	"Align Sequence in Best Frame";
	static final private String ShowPWallFrames = 	"Align Sequence in All Frames";
	
	static final private String ShowESTAlignments = 	"Contig Alignment";
	static final private String ShowTableOfSNPs = 	"Table of SNPs";
	
	static final private String ShowUnitransSeq = 	"Show sequence";

	static final private int SHOW_UT_OVERVIEW = 2;
	static final private int SHOW_UT_GO = 9;

	static final private int SHOW_PW_BEST_FRAME = 5;
	static final private int SHOW_PW_ALL_FRAMES = 6;
	
	static final private int SHOW_VIEW_OFF = 1;
	static final private int SHOW_EST_ALIGNMENTS = 7;
	static final private int SHOW_TABLE_OF_SNPS = 8;
	
	private MenuMapper menuUToverview = null;
	private MenuMapper menuUTGO = null;
	private MenuMapper menuPWalign = null; 
	private MenuMapper menuViewOff = null;
	
	private ContigOverviewPanel overviewPanel = null;
	private ContigGOPanel goPanel = null;
	private MainToolBarPanel pairBestPanel = null;
	private MainToolBarPanel pairAllPanel = null;
	private SNPMultiPanel snpPanel = null; 
	
	/************************************************
	 * DB hit view
	 * the number refers to the filter number
	 */
	static final private String AlignOffSeqShared = "Align shared DB hits - off";
	static final private String AlignFirst3Shared = "Align first 3 shared hits";
	static final private String Align0sequences =   "Align all hits";

	static final private String AlignOffSequences = "Align DB hits - off ";
	static final private String Align32Sequences = 	"Align best hit";
	static final private String AlignOVtable =		"Align DB hits table content";
	static final private String AlignSelect	   = 	"Align selected hit(s)";
	static final private String AlignSelectAll = 	"Align selected hit(s) in all frames";
	
	static final private int ALIGN_OFF_SEQUENCES = 1;
		
	static final private int ALIGN_BEST_SEQUENCES = 2; // best
	static final private int ALIGN_SELECTED = 3;
	static final private int ALIGN_SELECTED_ALL = 4;
	static final private int ALIGN_OV_TABLE = 5;
	
	static final private int ALIGN_FIRST3_SHARED = 6;
	static final private int ALIGN_ALL_SHARED = 7;

	private MenuMapper menuAlignOff = null;
	private MenuMapper menuBestHitAlign = null;
	private MenuMapper menuFirst3 = null;

	private MainToolBarPanel Hit1Panel = null;
	private MainToolBarPanel Hit2Panel = null;
	private MainToolBarPanel Hit4Panel = null;
	private MainToolBarPanel Hit8Panel = null;
	
	private MainToolBarPanel Hit32Panel = null;
	private MainToolBarPanel HitSLPanel = null;
	private MainToolBarPanel HitSLAPanel = null;	
	private MainToolBarPanel Hit0Panel = null;	
	private MainToolBarPanel HitF3Panel = null;

	private int filterType=0;
	/*******************************************************/
	private boolean internalSelect = false;
	private int nRecordNum;	

	private JPaveFrame paveFrame = null;
	private JComboBox displayDropDown = null;
	private JComboBox alignDropDown = null;

	private JPanel bottomPanel = null;
	private JPanel displayedJPanel = null;
	private TreeSet<String> selectedContigs = new TreeSet<String> ();
	private MainData ctgListData = null;
	private MainData loadedClusterData = null;
	private String strSelectedClones = ""; 
	private String [] displayedHits1 = null;
	private String [] displayedHits2 = null;
	private String goHit = null;
	
	/**********************************************************/
	private int [] prevContigDisplaySettings = null;
	
	//Keeps track of what sequences have been loaded
	private boolean bBuriedSequenceDetailLoaded = false;
	private boolean bBuriedSequenceLocationLoaded = false;
	//Used to signal if buried ESTs need to be loaded
	private boolean bLoadBuriedSequenceDetail = false;
	private boolean bLoadBuriedSequenceLocation = false;
	
    private static final long serialVersionUID = 1;
}
